#ifndef NATIVE_DOMAIN_COMPILING_SQL_MSSQLSCANNER_H
#define NATIVE_DOMAIN_COMPILING_SQL_MSSQLSCANNER_H

#ifndef NATIVE_DOMAIN_COMPILING_COMMON_STATUSSTACK_H
#include "Domain/Compiling/Common/StatusStack.h"
#endif
#ifndef NATIVE_DOMAIN_COMPILING_SQL_HEADERGATHER_H
#include "Domain/Compiling/Sql/HeaderGather.h"
#endif
#ifndef NATIVE_DOMAIN_COMPILING_SQL_VARIABLEGATHER_H
#include "Domain/Compiling/Sql/VariableGather.h"
#endif
#ifndef NATIVE_DOMAIN_COMPILING_SQL_COMMENT_H
#include "Domain/Compiling/Sql/Comment.h"
#endif

using namespace Native::Compiling;

#ifndef YY_DECL

#define	YY_DECL \
    int Arcane::Compiling::Sql::CMssqlScanner::Run()
#endif

#ifndef __FLEX_LEXER_H
#define yyFlexLexer CMssqlScannerFlexLexer
#include "FlexLexer.h"
#undef yyFlexLexer
#endif

namespace Native { namespace Compiling { namespace Sql
{
    NATIVE_DECLARE_CONST_OBJECT(CMssqlScanner, C_MSSQL_SCANNER);
    class NATIVE_LIBRARY_EXPORT CMssqlScanner :
        public CMssqlScannerFlexLexer,
        public CObject
    {
        enum EStage
        {
            STAGE_BODY,
            STAGE_PROCEDURE_DECLARATION,
            STAGE_FUNCTION_DECLARATION
        };

        NATIVE_DECLARE_OBJECT;

    protected:
        EStage _stage;
        int _sequence;
        CStatusStack _status_stack;
        CComment _comment;
        CHeaderGather _declaration_gather;
        CVariableGather _variable_gather;


    public:
        /** Create a new scanner object. The streams arg_yyin and arg_yyout default
        * to cin and cout, but that assignment is only made when initializing in
        * yylex(). */
        CMssqlScanner(istream* yy_in = 0, ostream* yy_out = 0);

        /** Required for virtual functions */
        virtual ~CMssqlScanner();

        /** This is the main lexing function. It is generated by flex according to
        * the macro declaration YY_DECL above. The generated bison parser then
        * calls this virtual function to fetch new tokens. */
        virtual int Run();

    protected:
        CString _TrimBlank(C_STRING& text);
        int _MakeSequence();
        void _BeginComment(size_t line, CComment::EStyle style);
    };
}}}

#endif